package com.jinlia.show.modules.system.service;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jinlia.show.modules.base.system.entity.SysRole;
import com.jinlia.show.modules.base.system.entity.SysRoleMenu;
import com.jinlia.show.modules.base.system.entity.SysUserRole;
import com.jinlia.show.modules.base.model.po.SysRolePO;
import com.jinlia.show.modules.base.system.service.SysRoleMapperService;
import com.jinlia.show.modules.base.system.service.SysRoleMenuMapperService;
import com.jinlia.show.modules.system.model.Option;
import com.jinlia.show.modules.base.model.form.RoleForm;
import com.jinlia.show.modules.base.model.query.RolePageQuery;
import com.jinlia.show.modules.system.service.ifc.ISysRoleService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SysRoleService extends SysRoleMapperService{

    @Autowired
    private  SysRoleMenuService roleMenuService;
    @Autowired
    private  SysUserRoleService userRoleService;





    /**
     * 保存角色
     *
     * @param entity 角色表单数据
     * @return {@link Boolean}
     */

    public boolean saveRole(SysRolePO entity) {
        Long roleId = entity.getId();
        // 编辑角色时，判断角色是否存在
        SysRole oldRole = null;
        if (roleId != null) {
            oldRole = this.getById(roleId);
        }

        String roleCode = entity.getCode();
        long count = this.count(new LambdaQueryWrapper<SysRole>()
                .ne(roleId != null, SysRole::getId, roleId)
                .and(wrapper ->
                        wrapper.eq(SysRole::getCode, roleCode).or().eq(SysRole::getName, entity.getName())
                ));
        SysRole sysRole = SysRolePO.toEntity(entity);
        return this.saveOrUpdate(sysRole);
    }

    /**
     * 获取角色表单数据
     *
     * @param roleId 角色ID
     * @return {@link RoleForm} – 角色表单数据
     */

    public SysRolePO getRoleForm(Long roleId) {
        SysRole entity = this.getById(roleId);
        return SysRolePO.fromEntity(entity);
    }

    /**
     * 修改角色状态
     *
     * @param roleId 角色ID
     * @param status 角色状态(1:启用；0:禁用)
     * @return {@link Boolean}
     */

    public boolean updateRoleStatus(Long roleId, Integer status) {

        SysRole role = this.getById(roleId);

        boolean result = this.updateById(role);
        if (result) {
            // 刷新角色的权限缓存
            roleMenuService.refreshRolePermsCache(role.getCode());
        }
        return result;
    }

    /**
     * 批量删除角色
     *
     * @param ids 角色ID，多个使用英文逗号(,)分割
     * @return {@link Boolean}
     */

    public boolean deleteRoles(String ids) {
        List<Long> roleIds = Arrays.stream(ids.split(","))
                .map(Long::parseLong).collect(Collectors.toList());

        for (Long roleId : roleIds) {
            SysRole role = this.getById(roleId);

            // 判断角色是否被用户关联
            boolean isRoleAssigned = userRoleService.hasAssignedUsers(roleId);

            boolean deleteResult = this.removeById(roleId);
            if (deleteResult) {
                // 删除成功，刷新权限缓存
                roleMenuService.refreshRolePermsCache(role.getCode());
            }
        }
        return true;
    }

    /**
     * 获取角色的菜单ID集合
     *
     * @param roleId 角色ID
     * @return 菜单ID集合(包括按钮权限ID)
     */

    public List<Long> getRoleMenuIds(Long roleId) {
        return roleMenuService.listMenuIdsByRoleId(roleId);
    }

    /**
     * 修改角色的资源权限
     *
     * @param roleId  角色ID
     * @param menuIds 菜单ID集合
     * @return {@link Boolean}
     */

    @Transactional
    @CacheEvict(cacheNames = "menu", key = "'routes'")
    public boolean assignMenusToRole(Long roleId, List<Long> menuIds) {
        SysRole role = this.getById(roleId);

        // 删除角色菜单
        roleMenuService.remove(
                new LambdaQueryWrapper<SysRoleMenu>()
                        .eq(SysRoleMenu::getRoleId, roleId)
        );
        // 新增角色菜单
//        if (CollectionUtil.isNotEmpty(menuIds)) {
//            List<SysRoleMenu> roleMenus = menuIds
//                    .stream()
//                    .map(menuId -> new SysRoleMenu(roleId, menuId))
//                    .collect(Collectors.toList());
//            sysRoleMenuMapperService.saveBatch(roleMenus);
//        }

        // 刷新角色的权限缓存
        roleMenuService.refreshRolePermsCache(role.getCode());
        return true;
    }

    /**
     * 获取最大范围的数据权限
     *
     * @param roles 角色编码集合
     * @return {@link Integer} – 数据权限范围
     */

    public Integer getMaximumDataScope(Set<String> roles) {
        return null;
    }

    public List<SysRole> getRolesByUserId(Long userId) {
        List<SysUserRole> list = userRoleService.lambdaQuery()
                .eq(SysUserRole::getUserId, userId)
                .list();
        List<Long> roleIds = list.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(roleIds)) {
            return Arrays.asList();
        }
        List<SysRole> listSysRole = this.lambdaQuery()
                .select(SysRole::getId, SysRole::getName, SysRole::getCode)
                .in(SysRole::getId, roleIds)
                .list();
        return listSysRole;
    }
}
